package com.violet.array;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Violet
 * @Date 2022/4/28
 * @Description 905 按奇偶排序数组
 * 给你一个整数数组 nums，将 nums 中的的所有偶数元素移动到数组的前面，后跟所有奇数元素
 *
 * 输入：nums = [3,1,2,4]
 * 输出：[2,4,3,1]
 * 解释：[4,2,3,1]、[2,4,1,3] 和 [4,2,1,3] 也会被视作正确答案。
 */
public class SortArrayByParity {

    public static void main(String[] args) {
        int[] test1 = {3, 1, 2, 4};
        int[] test2 = {};

        System.out.println(Arrays.toString(sortArrayByParity01(test1)));
        System.out.println(Arrays.toString(sortArrayByParity02(test1)));

        System.out.println(Arrays.toString(sortArrayByParity01(test2)));
        System.out.println(Arrays.toString(sortArrayByParity02(test2)));
    }

    public static int[] sortArrayByParity01(int[] nums) {
        List<Integer> numList = Arrays.stream(nums).boxed().collect(Collectors.toList());
        // 使用filter()获取到原数组中的奇数集合
        List<Integer> oddList = numList.stream().filter(integer -> integer % 2 != 0).collect(Collectors.toList());

        // 性能优于:
        // numList.removeAll(oddList);
        // numList.addAll(oddList);
        List<Integer> evenList = numList.stream().filter(integer -> integer % 2 == 0).collect(Collectors.toList());
        evenList.addAll(oddList);

        Integer[] result = evenList.toArray(new Integer[0]);
        return Arrays.stream(result).mapToInt(Integer::valueOf).toArray();
    }

    public static int[] sortArrayByParity02(int[] nums) {
        // 长度
        int length = nums.length;
        // 存储结果集的数组
        int[] result = new int[length];
        // 左指针
        int left = 0;
        // 右指针
        int right = length - 1;

        /*
         * 遍历，判断元素奇偶
         * 若为偶数，从左侧开始存，且将左指针 + 1
         * 若为奇数，从右侧开始存，且将右指针 - 1
         * */
        for (int num : nums) {
            if (num % 2 == 0) {
                result[left++] = num;
            } else {
                result[right--] = num;
            }
        }
        return result;
    }
}
